"""Functions to identify SNOMED terms in text"""

import sys
from sets import Set

from Lexicon import Lexicon
from PorterStemmer import stem
from DatabaseConnector import connection
import re

class MatrixCell:

    def __init__(self, p_ids, f_ids):
        self.p_ids = p_ids
        self.f_ids = f_ids


lexicon = Lexicon("LexSCT")

def stop_ratio_cull(dids):
    """Removes descriptions which have more stop words if there is a
    match with significantly fewer.
    """
    max_ratio = max(lexicon.get_stop_ratio(id_) for id_ in dids)
    if max_ratio > 0.9:
        threshold = 0.9
    else:
        threshold = max_ratio * .6
    return [id_ for id_ in dids if lexicon.get_stop_ratio(id_) > threshold]

def get_matching_matrix(med_terms):

    matrix = {}

    for c, word in enumerate(med_terms):
        p_ids = Set(lexicon.get_lex_ids(word))
        f_ids = []

        for id_ in p_ids:
            if lexicon.get_lex_count(id_) == 1:
                f_ids.append(id_)

        #if f_ids:
        #    f_ids = stop_ratio_cull(f_ids)
        f_ids = Set(f_ids)
        
        matrix[(c, c)] = MatrixCell(p_ids, f_ids)
        
        for r in xrange(c-1, -1, -1):
            p_ids = matrix[(r, c-1)].p_ids
            p_ids = p_ids.intersection(matrix[(r+1, c)].p_ids)
            #print (r, c), p_ids
            f_ids = []

            for id_ in p_ids:
                #print c - r + 1, id_, lexicon.get_lex_count(id_), type(lexicon.get_lex_count(id_))
                if lexicon.get_lex_count(id_) == c - r + 1:
                    #print id_
                    f_ids.append(id_)
            #if f_ids:
            #    f_ids = stop_ratio_cull(f_ids)
            f_ids = Set(f_ids)
            #if f_ids:
            #    print r, c, f_ids

            matrix[(r, c)] = MatrixCell(p_ids, f_ids)

    #for k in matrix:
    #    print k, matrix[k].f_ids
    return matrix

def find_best_matches(matrix, n):
    best_matches = []
    r = 0
    while r < n:
        for c in xrange(n-1 , r-1, -1):
            #print r, c
            cell = matrix.get((r, c), None)
            if cell:
                if cell.f_ids:
                    best_matches.append(((r, c+1), cell.f_ids))
                    r = c
                    break
        r = r + 1

    return best_matches

stoplist = {}
# def load_stopwords():
#     for line in file("LexSCT/stoplist", "r"):
#         line = line.strip()
#         if line and line[0]!="#":
#             stoplist[line] = None
#     return stoplist
def load_stopwords():
    cursor = connection.cursor()
    cursor.execute("SELECT * FROM information_schema.`TABLES` T where table_name = 'stoplist' and table_schema = 'snomed'")
    if cursor.rowcount == 0:
         print "The table doesn't exist. \nPlease check if the installation process is successful."
    else:
         cursor.execute("SELECT STOPWORD FROM SNOMED.STOPLIST")
         for tuple in cursor.fetchall():
             line = str(tuple).strip(",\"()'")
             if line and line[0]!="#" and line!="\n":
                stoplist[line] = None
    return stoplist

            
def words(text):
    return re.findall('[a-z]+', text.lower())

def match_token(sent):
    return find_best_matches(get_matching_matrix(sent), len(sent))

def match_sentence(sent):
    if not stoplist:
        load_stopwords()
    s = [stem(token) for token in sent if token not in stoplist]
#    print s
    for ((s, e), ids) in match_token(s):
         yield ((s, e), list(ids))         
    

#if __name__ == "__main__":
#    conc_list = {}
#    cursor = connection.cursor()
#    cursor.execute("SELECT * FROM resulttext_table r where r.`RequestID` = 1")
#    
#    for tuple in cursor.fetchall():
##    reqid = str(reqid).strip('L')
#        text = str(tuple[1]).strip('"(),')
#        reqid = tuple[0]
#        print reqid, text
#        for ((s, e), ids) in match_sentence(text.split()):
#            print s, e, ids
#_DEBUG_ = True
#dictionary = {}
#from DatabaseConnector import connection
#cursor = connection.cursor()
#if _DEBUG_:
#        sys.stderr.write("Loading dictionary..")
#cursor.execute("select `Concept ID`, `Description ID` from snomed.sct_descriptions_20070731")
#
#for i, tuple in enumerate(cursor):
#    if _DEBUG_:
#             if i % 10000 == 0:
#                 sys.stderr.write(".")
#    dictionary[tuple[1]] = tuple[0]
#if _DEBUG_:
#        sys.stderr.write(" %s entries\n" % i)
#
#conc = []
#from PorterStemmer import stem
#s = "whole body scan using technetium".split()
#for ((s, e), ids) in match_sentence(s):
#    for id in ids:
#        if conc.count(dictionary[id]) == 0:
#            conc.append(dictionary[id])
#print conc